#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "../common/globaldef.h"
#include "../common/globalVai.h"
/*
*******************************************************************************
*			           constants and define declarations
*******************************************************************************
*/
/* amplitude used in QPSK */
#define D_QPSK		0.7071

/* amplitudes used in 16QAM */
#define A_16QAM		0.3162
#define A3_16QAM	0.9486





int Modulator(int M_Type, int SymbolIndex , int * Source, struct Complex * Symbol)
{
	int i;
	int j;// symbol index 
	int k;
	int bit_string;// used in 16QAM 
	struct Complex Symbol1[895];// temp 


	if(M_Type==0)// QPSK 
	{
		for(i = (SymbolIndex * 895); i<( (SymbolIndex + 1) * 895 ); i++)
		{
			j = i % 895;
		    switch ( Source[2*i] )
			{
		        case 0:
			        Symbol1[j].real =  D_QPSK;
			        break;
		        case 1:
			        Symbol1[j].real = -D_QPSK;
			        break;
		        default:
			        return 0;
			}
		    switch ( Source[2*i + 1] )
			{
		        case 0:
			        Symbol1[j].imag =  D_QPSK;
			        break;
		        case 1:
			        Symbol1[j].imag = -D_QPSK;
			        break;
		        default:
			        return 0;
			}
		}// end of for 
	}

	else if(M_Type==1)// 16QAM 
	{
		for(i = (SymbolIndex * 895); i<( (SymbolIndex + 1) * 895 ); i++)
		{
			j = i % 895;
		    // I symbols 
		    bit_string = (Source[4*i + 1] << 1) | Source[4*i];
		    switch ( bit_string )
			{

		        case 0:
			        Symbol1[j].real =  A3_16QAM;
			        break;
		        case 1:
			        Symbol1[j].real =  A_16QAM;
			        break;
		        case 3:
			        Symbol1[j].real = -A_16QAM;
			        break;
		        case 2:
			        Symbol1[j].real = -A3_16QAM;
			        break;
		        default:
			        return 0;
			}

		    // Q symbols 
		    bit_string = (Source[4*i + 3] << 1) | Source[4*i + 2];
		    switch ( bit_string )
			{

		        case 0:
			        Symbol1[j].imag =  A3_16QAM;
			        break;
		        case 1:
			        Symbol1[j].imag =  A_16QAM;
			        break;
		        case 3:
			        Symbol1[j].imag = -A_16QAM;
			        break;
		        case 2:
			        Symbol1[j].imag = -A3_16QAM;
			        break;
		        default:
			        return 0;
			}
		}// end of for 
	}
	else
	{
		return 0;
	}

	// modify 

	for(i = 0; i<1120; i++)
	{
		Symbol[i].real = 0;
		Symbol[i].imag = 0;
	}

	// leave the space to insert pilot 
	j = 0;// Symbol index 

	// CP length is 96 
	for(i = 12; i<=138; i++)
	{
		for(k = 1; k<=7; k++)// 7 symbols 
		{
		    Symbol[i*8 + k].real = Symbol1[j].real;
		    Symbol[i*8 + k].imag = Symbol1[j].imag;
			j++;
		}
	}
	for(i = 139*8+1; i<=1118; i++)// the last 6 symbols 
	{
		Symbol[i].real = Symbol1[j].real;
		Symbol[i].imag = Symbol1[j].imag;
		j++;
	}
	return 1;
}
